﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Xml;
using LorraineSec.DatabaseLib;

namespace LorraineSec.DatabaseLib.DataObjects
{
    /// <summary>
    /// A wrapper class for the Database Asset type
    /// </summary>
    public class Asset
    {
        #region Constants
        private const string ROOT_STR = XmlDatabase.ASSET;
        private const string ID_STR = XmlDatabase.ID;
        private const string NAME_STR = XmlDatabase.NAME;
        private const string COMPARTMENT_STR = XmlDatabase.COMPID;
        private const string USER_STR = XmlDatabase.USERID;
        private const string RFID_STR = XmlDatabase.RFID;
        #endregion

        private XmlNode xmlAssetRoot;
        private XmlNode xmlName;
        private XmlNode xmlCompartmentID;
        private XmlNode xmlUserID;
        private XmlNode xmlRFID;

        /// <summary>
        /// Constructs an Asset wrapper object
        /// </summary>
        /// <param name="node">The Database XmlNode to wrap</param>
        public Asset(XmlNode node)
        {
            xmlAssetRoot = node;
            xmlName = xmlAssetRoot.SelectSingleNode(NAME_STR);
            xmlCompartmentID = xmlAssetRoot.SelectSingleNode(COMPARTMENT_STR);
            xmlUserID = xmlAssetRoot.SelectSingleNode(USER_STR);
            xmlRFID = xmlAssetRoot.SelectSingleNode(RFID_STR);
        }

        /// <summary>
        /// Constructs a list of wrapped Assets from the database.
        /// </summary>
        /// <param name="db">The database.</param>
        /// <returns>A list of wrapped Assets.</returns>
        public static List<Asset> GetList(XmlDatabase db)
        {
            List<Asset> retList = new List<Asset>();
            if (db.assets != null)
            {
                XmlNodeList nodeList = db.assets.SelectNodes(ROOT_STR);
                retList.Capacity = nodeList.Count;
                foreach (XmlNode n in nodeList)
                {
                    retList.Add(new Asset(n));
                }
            }
            return retList;
        }

        /// <summary>
        /// Implicitly converts a XmlNode to an Asset.
        /// </summary>
        /// <param name="node">The XmlNode to be wrapped.</param>
        /// <returns>The Asset representation of the wrapped node.</returns>
        public static implicit operator Asset(XmlNode node)
        {
            return new Asset(node);
        }

        /// <summary>
        /// Explicitly converts an Asset wrapper to a Database XmlNode.
        /// </summary>
        /// <param name="u">The Asset object to unwrap.</param>
        /// <returns>An unwrapped XmlNode.</returns>
        public static explicit operator XmlNode(Asset u)
        {
            return u.xmlAssetRoot;
        }

        /// <summary>
        /// The ID of the Asset
        /// </summary>
        public uint ID
        {
            get { return UInt32.Parse(xmlAssetRoot.Attributes[ID_STR].Value); }
        }

        /// <summary>
        /// The name of the asset.
        /// </summary>
        public string Name
        {
            get { return xmlName.InnerText; }
            set { xmlName.InnerText = value; }
        }

        /// <summary>
        /// The compartment ID the asset belongs to.
        /// </summary>
        public uint CompartmentID
        {
            get { return UInt32.Parse(xmlCompartmentID.InnerText); }
            set { xmlCompartmentID.InnerText = value.ToString(); }
        }

        /// <summary>
        /// The user ID that currently possesses the asset.
        /// </summary>
        public uint UserID
        {
            get { return UInt32.Parse(xmlUserID.InnerText); }
            set { xmlUserID.InnerText = value.ToString(); }
        }

        public string RFID
        {
            get { return xmlRFID.InnerText; }
            set { xmlRFID.InnerText = value; }
        }

        public override string ToString()
        {
            return Name;
        }
    }
}
